<?php
namespace app\common\model;

use app\index\model\Logs;
use think\Db;
use think\Env;
use think\Log;
use think\Model;
use think\Request;

class SuperModel extends Model
{

    //记录分页
    //
    private $_page   = null;
    private $_rows   = null;
    private $_offset = null;

    //字段排序
    //
    protected $_order = [];

    //继承父类initialize()

    protected function initialize()
    {
        parent::initialize();

        //对数据库执行的任何SQL操作进行监听
        self::logSql();
    }

    /**
     * 记录SQL脚本
     *
     * @return   [void]
     */
    public static function logSql($level = 'sql', $folder = 'sql')
    {

        //初始化调试监听文件日志路径
        //
        Log::init([
            'type'        => 'File',
            'path'        => APP_PATH . 'logs' . DS . $folder . DS,

            //ERROR 和SQL日志单独记录
            'apart_level' => ['error', 'sql'],
        ]);

        //对数据库执行的任何SQL操作进行监听
        //
        Db::listen(function ($sql, $time, $explain) {

            // 记录SQL
            Log::record($sql . ' [' . $time . 's]', 'sql');

            // 获取环境变量 如果不存在则使用默认值root
            $sql_explain = Env::get('sql_explain', false);

            if ($sql_explain) {
                
                // 查看性能分析结果
                Log::record($explain, 'sql');
            }

        });
    }

    /**
     * 列表(主键列表，条件数组，闭包查询)
     *
     * @param    array $param 查询条件
     * @return   void
     */
    public function doList($param = null)
    {

        $_offset = $this->_offset;
        $_rows   = $this->_rows;

        try {
            //排序判断
            if (!empty($this->_order)) {

                $_order = [];

                //排序拼接
                foreach ($this->_order as $k->$v) {
                    array_push($_order, $k . ' ' . $v);
                }

                $order = join(',', $_order);

                //分页判断

                if (!empty($_rows) && !empty($_offset)) {

                    //查询数据
                    $result = self::all($param)->limit($_offset, $_rows)->order($order);
                } else if (!empty($_rows)) {

                    //查询数据
                    $result = self::all($param)->limit($_rows)->order($order);
                } else {
                    //查询数据
                    $result = self::all($param)->order($order);
                }
            } else {
                //分页判断

                if (!empty($_rows) && !empty($_offset)) {

                    //查询数据
                    $result = self::all($param)->limit($_offset, $_rows);
                } else if (!empty($_rows)) {

                    //查询数据
                    $result = self::all($param)->limit($_rows);
                } else {
                    //查询数据
                    $result = self::all($param);
                }
            }

            $rows = [];

            foreach ($result as $data) {

                $item = $data->getData();
                array_push($rows, $item);
            }

            //返回结果
            $res = array();

            $total = count($rows);

            if ($total > 0) {
                $res['rows']  = $rows;
                $res['total'] = $total;
            } else {
                $res['total'] = 0;
                $res['rows']  = array();
            }

            return ($res);

        } catch (\Exception $e) {
            throw new \think\Exception('异常消息:' . $e->getMessage());
        }
    }

    /**
     * 新增
     *
     * @return   integer|false
     */
    public function doAdd(Request $request)
    {

        $id          = $this->allowField(true)->save($request->param());
        $rtn['data'] = ['id' => $id];

        //返回信息
        return ($rtn);

    }

    /**
     * 删除记录
     *
     * @param    int $id 记录主键
     * @return   void
     */
    public function doDelete(Request $request)
    {
        $res = $this->execDelete($request->param('id'));
        return ($res);
    }

    /**
     * 软删除
     *
     * @param    int $id 记录主键
     * @return   void
     */
    public function doSoftDelete(Request $request)
    {
        $res = $this->execDelete($request->param('id'), true);
        return ($res);
    }

    /**
     * 动态删除
     *
     * @param    boolean $isSoftDelete 软删除标记
     * @return   void
     */
    public function execDelete($id, $isSoftDelete = false)
    {

        //按主键删除或软删除
        $affected = $isSoftDelete ? self::destroy($id) : self::destroy($id, true);

        //根据请求返回信息
        return ($affected);

    }

    /**
     * 批量删除
     */
    public function doBatDelete(Request $request)
    {
        $ids = json_decode($request->param('id'), true);
        $res = $this->execBatDelete($ids);

        return ($res);
    }

    /**
     * 批量软删除
     */
    public function doSoftBatDelete(Request $request)
    {
        $ids = json_decode($request->param('id'), true);
        return ($this->execBatDelete($ids, true));
    }

    /**
     * 执行批量删除
     * 成功删除的记录数
     */
    public function execBatDelete($ids, $isSoftDelete = false)
    {

        //根据对象主键,删除数据
        $affected = $isSoftDelete ? self::destroy($ids) : self::destroy($ids, true);

        //根据请求返回信息
        return ($affected);
    }

    /**
     * 更新数据模型
     *
     * @return   void
     */
    public function doUpdate(Request $request)
    {

        //过滤请求数组中非数据表数据
        $res = self::allowField(true)
            ->isUpdate(true)
            ->save($request->param(), ['id' => $request->param('id')]);

        //返回信息
        return ($res);

    }

    /**
     * 更新数据模型多条记录
     *
     * @return   void
     */
    public function doUpdateAll($data, $condition)
    {

        $res = self::updateAll($data, $condition);
        return ($res);
    }

    /**
     * 请求操作日志
     *
     * @param    array $output 返回信息
     * @param    boolean $authorized 登录标志
     * @return   void
     */
    public function doLog($rtn, $authorized = true)
    {

        $Logs = new Logs;
        return $Logs->doLog($rtn, $authorized);
    }

    /**
     * 设置分页
     *
     * @param    array $param 分页参数
     * @return   void
     */
    public function setPagination($page, $rows, $offset)
    {
        #增加分页限制参数
        $this->page   = $page; #是否预先设置了页码,如有没有则当前默认页码为1
        $this->rows   = $rows; #是否预先设置了单页面行数,如没有则按照每页行数为25
        $this->offset = $offset; #根据当前页码或请求参数设置偏移量
    }
    /**
     * Db类SQL原生查询
     */
    public function dbQuery($_sql)
    {
        try {

            $rows = (!empty($_sql)) ? Db::query($_sql) : [];

            //返回结果
            $res = array();

            $total = count($rows);

            if ($total > 0) {
                $res['rows']  = $rows;
                $res['total'] = $total;
            } else {
                $res['total'] = 0;
                $res['rows']  = array();
            }

            //请求类型返回
            _callback($res);

        } catch (\Exception $e) {
            throw new \think\Exception('异常消息:' . $e->getMessage());
        }
    }
}
